﻿using Engine;
using Engine.Graphics;

namespace Game
{
    public abstract class TestGunsBlock : Block
    {
        public BlockMesh m_gunMesh = new BlockMesh();

        public BlockMesh m_boltMesh = new BlockMesh();

        public BlockMesh m_armsMesh = new BlockMesh();

        public Model Model { get; set; }

        public Texture2D Texture { get; set; }

        public TestGunsBlock(string model, string texture)
        {
            Model = ContentManager.Get<Model>(model);
            Texture = ContentManager.Get<Texture2D>(texture);
        }

        public override void Initialize()
        {
            base.Initialize();
            ModelMesh modelMesh = Model.FindMesh("Gun");
            ModelMesh modelMesh2 = Model.FindMesh("Bolt");
            ModelMesh modelMesh3 = Model.FindMesh("LeftHand");
            ModelMesh modelMesh4 = Model.FindMesh("RightHand");
            m_gunMesh.AppendModelMeshPart(modelMesh.MeshParts[0], BlockMesh.GetBoneAbsoluteTransform(modelMesh.ParentBone), makeEmissive: false, flipWindingOrder: false, doubleSided: false, flipNormals: false, Color.White);
            m_boltMesh.AppendModelMeshPart(modelMesh2.MeshParts[0], BlockMesh.GetBoneAbsoluteTransform(modelMesh2.ParentBone), makeEmissive: false, flipWindingOrder: false, doubleSided: false, flipNormals: false, Color.White);
            m_armsMesh.AppendModelMeshPart(modelMesh3.MeshParts[0], BlockMesh.GetBoneAbsoluteTransform(modelMesh3.ParentBone), makeEmissive: false, flipWindingOrder: false, doubleSided: false, flipNormals: false, Color.White);
            m_armsMesh.AppendModelMeshPart(modelMesh4.MeshParts[0], BlockMesh.GetBoneAbsoluteTransform(modelMesh4.ParentBone), makeEmissive: false, flipWindingOrder: false, doubleSided: false, flipNormals: false, Color.White);
        }

        public override void DrawBlock(PrimitivesRenderer3D primitivesRenderer, int value, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
        {
            DrawGun(primitivesRenderer, color, size, ref matrix, environmentData);
            DrawBolt(primitivesRenderer, color, size, ref matrix, environmentData);
        }

        public void DrawGun(PrimitivesRenderer3D primitivesRenderer, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
        {
            BlocksManager.DrawMeshBlock(primitivesRenderer, m_gunMesh, Texture, color, 2f * size, ref matrix, environmentData);
        }

        public void DrawBolt(PrimitivesRenderer3D primitivesRenderer, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
        {
            BlocksManager.DrawMeshBlock(primitivesRenderer, m_boltMesh, Texture, color, 2f * size, ref matrix, environmentData);
        }

        public void DrawArms(PrimitivesRenderer3D primitivesRenderer, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData, Texture2D texture)
        {
            BlocksManager.DrawMeshBlock(primitivesRenderer, m_armsMesh, texture, color, 2f * size, ref matrix, environmentData);
        }

        public override void GenerateTerrainVertices(BlockGeometryGenerator generator, TerrainGeometry geometry, int value, int x, int y, int z)
        {
        }

        public override bool IsSwapAnimationNeeded(int oldValue, int newValue)
        {
            if (Terrain.ExtractContents(oldValue) != Terrain.ExtractContents(newValue))
            {
                return true;
            }

            int bulletNum = GetBulletNum(Terrain.ExtractData(oldValue));
            int bulletNum2 = GetBulletNum(Terrain.ExtractData(newValue));
            return bulletNum2 > bulletNum;
        }

        public static int GetBulletNum(int data)
        {
            return (data - data % (int)MathUtils.Pow(2f, 9f)) / (int)MathUtils.Pow(2f, 9f);
        }

        public static int SetBulletNum(int data, int bulletNum)
        {
            return bulletNum * (int)MathUtils.Pow(2f, 9f) + data % (int)MathUtils.Pow(2f, 9f);
        }

        public override int GetDamage(int value)
        {
            int num = Terrain.ExtractData(value);
            return num % (int)MathUtils.Pow(2f, 9f);
        }

        public override int SetDamage(int value, int damage)
        {
            int num = Terrain.ExtractData(value);
            int data = num - num % (int)MathUtils.Pow(2f, 9f) + damage;
            return Terrain.ReplaceData(value, data);
        }
    }
}